package com.cl.code.generate.source.database;

import com.cl.code.generate.source.database.entity.TableMetadata;

import java.net.URI;
import java.net.URISyntaxException;
import java.sql.*;

/**
 * 数据库连接器，负责管理数据库连接和获取表元数据
 *
 * @author chengliang
 * @since 1.0.0
 */
public class DatabaseConnector {
    private String url;
    private String user;
    private String password;
    private Connection connection;

    /**
     * 使用数据库连接参数创建连接器
     *
     * @param url      数据库连接URL
     * @param user     数据库用户名
     * @param password 数据库密码
     */
    public DatabaseConnector(String url, String user, String password) {
        try {
            // JDBC URL特殊处理：替换jdbc:前缀
            String uriStr = url.replaceFirst("jdbc:", "");
            URI uri = new URI(uriStr);
            String query = uri.getQuery();
            if (query == null || !query.contains("useInformationSchema=true")) {
                StringBuilder sb = new StringBuilder();
                if (query != null) {
                    sb.append(query).append("&");
                }
                sb.append("useInformationSchema=true");
                String newQuery = sb.toString();
                // 重新构建URI时要保留jdbc:前缀
                uri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), newQuery, uri.getFragment());
                url = "jdbc:" + uri;
            }
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException("Invalid JDBC URL", e);
        }
        this.url = url;
        this.user = user;
        this.password = password;
    }

    /**
     * 使用现有连接创建连接器
     *
     * @param connection 已建立的数据库连接
     */
    public DatabaseConnector(Connection connection) {
        this.connection = connection;
    }

    /**
     * 获取数据库连接
     *
     * @return 数据库连接对象
     */
    public Connection getConnection() throws SQLException {
        if (connection != null) {
            return connection;
        }
        return DriverManager.getConnection(url, user, password);
    }

    /**
     * 获取表字段元数据（包含字段注释）
     *
     * @param tableName 表名
     * @return 表字段元数据结果集（包含COLUMN_NAME, TYPE_NAME, REMARKS等字段）
     */
    public TableMetadata getTableMetadata(String tableName) throws SQLException {
        Connection conn = getConnection();
        DatabaseMetaData metaData = conn.getMetaData();
        String catalog = conn.getCatalog();

        // 获取表信息
        ResultSet tables = metaData.getTables(catalog, null, tableName, null);

        // 获取列信息
        ResultSet columns = metaData.getColumns(catalog, null, tableName, null);

        return new TableMetadata(tables, columns);
    }
}